package org.example.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.java.Log;
import org.example.bean.Category;
import org.example.configs.OssConfig;
import org.example.dao.CategoryMapper;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.List;
import java.util.UUID;

@Service
@AllArgsConstructor
@Log
public class CategoryServiceImpl implements CategoryService{
    private final CategoryMapper categoryMapper;
    private final OssConfig ossConfig;
    private final OSS ossClient;
    @Override
    @Transactional
    //当新增货修改了种类时，需要清楚所有相关的缓存
    //“categories” :是缓存的名称
    //allEntries = true : 表示清除所有的缓存
    @CacheEvict(value = "categories",allEntries = true) //添加缓存清除
    public Category addCategory(Category category) {
        //第一步上传图片到Oss
        String originalFilename = category.getIcoImgFile().getOriginalFilename();//文件名
        String fileExtension="";//文件扩展名
        if(originalFilename.contains(".")&&originalFilename!=null){
            fileExtension=originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        System.out.println("原文件名："+originalFilename+"\t扩展名"+fileExtension);
        String objectKey="files/"+ UUID.randomUUID().toString()+fileExtension; //保存的对象在oss中的地址
        PutObjectRequest putObjectRequest=null;
        try {
            putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), objectKey, category.getIcoImgFile().getInputStream());
            ossClient.putObject(putObjectRequest);   //上传到Oss

            String fileUrl = ossConfig.getUrlPrefix() + File.separator + objectKey;
            category.setIcon(fileUrl);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("上传文件到OSS失败"+ e.getMessage());
            throw new RuntimeException("上传文件到OSS失败"+e.getMessage());
        }

        categoryMapper.insert(category);
        return category;
    }

    //根据状态查询分类信息
    @Override
    //启用缓存：
    //value="banners" : 缓存的名称，所有轮播图相关的缓存都存放在这个命名空间下
    //key="#bannerStatus!=null ? 'status_'+#bannerStatus : 'all'" : 缓存的key，这里使用bannerStatus作为key，因为根据状态查询轮播图是一个固定的操作，所以可以缓存
    //  - 如果bannerStatus为null，缓存的key为"all"，表示查询所有轮播图
    //  - 如果bannerStatus不为null，缓存的key为"status_"+bannerStatus，例如status_1表示查询状态为1的轮播图
    //这个策略可以区分不同状态的轮播图列表，同时也有一个缓存所有轮播图的入口，例如status_1和status_2的轮播图是不同的，所以可以缓存
    //key使用了spring el表达式，根据bannerStatus是否为null来动态生成key
    //condition="#bannerStatus != null" : 缓存的条件，只有当bannerStatus不为null时才缓存
    @Cacheable(value = "categories", keyGenerator = "categoryKeyGenerator")
    public List<Category> getCategories(Integer categoryStatus) {
        //mybatis plus 中的条件查询语句
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        if(categoryStatus!=null && categoryStatus!=-1){
            wrapper.eq(Category::getCategory_status,categoryStatus);
        }
        return categoryMapper.selectList(wrapper);
    }


    //根据分类id查询分类信息
    @Override
//    @Cacheable(value = "categories", key = "#categoryId")
    public Category getCategoryById(Integer categoryId) {
        //mybatis plus 中的自带根据id查询语句
        return this.categoryMapper.selectById(categoryId);
    }

    //根据id修改类别的状态
    @Override
    @Transactional
    @CacheEvict(value = "categories",allEntries = true) //添加缓存清除
    public Category updateCategoryStatus(Integer categoryId, Integer category_status) {
        Category category = this.categoryMapper.selectById(categoryId);
        if(category==null){
            throw new RuntimeException("分类不存在"+categoryId);
        }
        category.setCategory_status(category_status);
        this.categoryMapper.updateById(category);
        return category;
//        return this.categoryMapper.updateById(category)>0;
    }

    //更新分类信息
    @Override
    @Transactional
    @CacheEvict(value = "categories",allEntries = true) //添加缓存清除
    public Category updateCategory(Category category) {
        Category oldCategory = this.categoryMapper.selectById(category.getCategory_id());
        if(oldCategory==null){
            throw new RuntimeException("分类不存在"+category.getCategory_id());
        }
        oldCategory.setCategory_status(category.getCategory_status());
        oldCategory.setLink_url(category.getLink_url());
        oldCategory.setCategory_name(category.getCategory_name());
        if(category.getIcoImgFile()!=null){
            //上传新图片
            String originalFilename = category.getIcoImgFile().getOriginalFilename();//文件名
            String fileExtension="";//文件扩展名
            if(originalFilename.contains(".")&&originalFilename!=null){
                fileExtension=originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            System.out.println("原文件名："+originalFilename+"\t扩展名"+fileExtension);
            String objectKey="files/"+ UUID.randomUUID().toString()+fileExtension; //保存的对象在oss中的地址
            try {
                PutObjectRequest putObjectRequest = new PutObjectRequest(ossConfig.getBucketName(), objectKey, category.getIcoImgFile().getInputStream());
                ossClient.putObject(putObjectRequest);
                String fileUrl = ossConfig.getUrlPrefix() + File.separator + objectKey;
                oldCategory.setIcon(fileUrl);
            } catch (Exception e) {
                e.printStackTrace();
                log.info("上传文件到OSS失败"+ e.getMessage());
                throw new RuntimeException("上传文件到OSS失败"+e.getMessage());
            }
        }
        this.categoryMapper.updateById(oldCategory);
        return oldCategory;
    }
}
